local assets =
{
    Asset("ANIM", "anim/electronic_ball.zip"),
    Asset("SOUND", "sound/chess.fsb"),
}

local AREAATTACK_MUST_TAGS = { "_combat" }
local AREA_EXCLUDE_TAGS = { "INLIMBO", "notarget", "noattack", "flight", "invisible", "playerghost" }
local function areaAttack(owner, target)
    local hitcount = 0
    local excludetags = AREA_EXCLUDE_TAGS
    local x, y, z = target.Transform:GetWorldPosition()
    local ents = TheSim:FindEntities(x, y, z, 5, AREAATTACK_MUST_TAGS, excludetags)
    for i, ent in ipairs(ents) do
        if ent ~= target and
            ent ~= owner and
            owner.components.combat:IsValidTarget(ent) then
            local weapon = owner ~= nil and owner.components.inventory ~= nil and owner.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
            ent.components.combat:GetAttacked(owner, owner.components.combat:CalcDamage(ent, weapon, .5))
            hitcount = hitcount + 1
        end
    end
end

local function OnHit(inst, owner, target)
    if owner ~= nil and owner:HasTag("suit_wx78linghter") then 
        -- 套装提供特殊击中效果
        SpawnPrefab("wx78_charge_hit_big").Transform:SetPosition(target.Transform:GetWorldPosition())
        areaAttack(owner, target)
    else
        SpawnPrefab("wx78_charge_hit").Transform:SetPosition(inst.Transform:GetWorldPosition())
    end
    inst:Remove()
end

local function OnAnimOver(inst)
    inst:DoTaskInTime(.3, inst.Remove)
end

local function OnThrown(inst)
    inst:ListenForEvent("animover", OnAnimOver)
end

local function OnMiss(inst, owner, target)
    local weapon = owner ~= nil and owner.components.inventory ~= nil and owner.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
    if weapon ~= nil and weapon.prefab == "wx78_linghter_sword" and weapon.components.finiteuses ~= nil then 
        weapon.components.finiteuses:Use()
    end
    inst:Remove()
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)
    RemovePhysicsColliders(inst)

    inst.Transform:SetFourFaced()

    inst.AnimState:SetBank("electronic_ball")
    inst.AnimState:SetBuild("electronic_ball")
    inst.AnimState:PlayAnimation("idle", true)

    inst.Transform:SetScale(.7, .7, 1)

    inst.entity:AddLight()
    inst.Light:SetRadius(1)
    inst.Light:SetFalloff(.8)
    inst.Light:SetIntensity(.8)
    inst.Light:SetColour(12 / 255, 25 / 255, 250 / 255)
    inst.Light:Enable(true)

    --projectile (from projectile component) added to pristine state for optimization
    inst:AddTag("projectile")

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst.persists = false

    inst:AddComponent("projectile")
    inst.components.projectile:SetSpeed(40)
    inst.components.projectile:SetHoming(false)
    inst.components.projectile:SetHitDist(1)
    inst.components.projectile:SetOnHitFn(OnHit)
    inst.components.projectile:SetOnMissFn(OnMiss)
    inst.components.projectile:SetOnThrownFn(OnThrown)

    return inst
end

local function PlayHitSound(proxy)
    local inst = CreateEntity()

    --[[Non-networked entity]]

    inst.entity:AddTransform()
    inst.entity:AddSoundEmitter()

    inst.Transform:SetFromProxy(proxy.GUID)

    inst.SoundEmitter:PlaySound("dontstarve/creatures/bishop/shotexplo")

    inst:Remove()
end

local function hit_fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddNetwork()

    inst:AddTag("FX")

    --Dedicated server does not need to spawn the local fx
    if not TheNet:IsDedicated() then
        --Delay one frame in case we are about to be removed
        inst:DoTaskInTime(0, PlayHitSound)
    end

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst.persists = false
    inst:DoTaskInTime(.5, inst.Remove)

    return inst
end

local function hit_fn_big()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddNetwork()
    inst.entity:AddAnimState()

    inst.AnimState:SetBank("electronic_ball")
    inst.AnimState:SetBuild("electronic_ball")
    inst.AnimState:PlayAnimation("idle", true)

    inst.Transform:SetScale(4, 2, 4)

    inst.entity:AddLight()
    inst.Light:SetRadius(3)
    inst.Light:SetFalloff(.8)
    inst.Light:SetIntensity(.8)
    inst.Light:SetColour(12 / 255, 25 / 255, 250 / 255)
    inst.Light:Enable(true)

    inst:AddTag("FX")

    --Dedicated server does not need to spawn the local fx
    if not TheNet:IsDedicated() then
        --Delay one frame in case we are about to be removed
        inst:DoTaskInTime(0, PlayHitSound)
    end

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst.persists = false
    inst:DoTaskInTime(.5, inst.Remove)

    return inst
end

return Prefab("wx78_charge", fn, assets),
    Prefab("wx78_charge_hit", hit_fn),
    Prefab("wx78_charge_hit_big", hit_fn_big, assets)